﻿//-----------------------------------------------------------------------
// <copyright file="Form1.cs" company="zDimension">
//     Copyright (c) 2013 zDimension. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace VM
{
    using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

    /// <summary>
    /// TODO: Provide summary section in the documentation header.
    /// </summary>
    public partial class MainWindow : Form
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="T:Form1"/> class.
        /// </summary>
        public MainWindow()
        {
            this.InitializeComponent();
        }

        private void loadScriptToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {

            }
        }
        IList<Variable> vars = new List<Variable>();
        IList<Function> funcs = new List<Function>();
        bool ConsoleImpl = false;
        bool StringImpl = false;
        public void Run(string code)
        {
            bool isInFunc = false;
            string tmpCode = "";
            string funcname = "";
            foreach (string cmd in code.Split('\n'))
            {
                if (cmd.StartsWith("#use "))
                {
                    if (!isInFunc)
                    {
                        string toImpl = cmd.Substring(5);
                        if (toImpl == "String << Core")
                        {
                            StringImpl = true;
                        }
                        else if (toImpl == "Console << Core")
                        {
                            ConsoleImpl = true;
                        }
                        else
                        {
                            MessageBox.Show("Error: Invalid '#use'");
                            break;
                        }
                    }
                    else
                    {
                        MessageBox.Show("Error: #lib in a function");
                        break;
                    }
                }
                else if (cmd.StartsWith("#inc "))
                {
                    if (!isInFunc)
                    {
                    
                    }
                    else
                    {
                        MessageBox.Show("Error: #inc in a function");
                        break;
                    }
                }
                else if ((cmd.StartsWith("begin ")))
                {
                    if (!isInFunc)
                    {
                        funcname = cmd.Replace("begin ", "");
                    isInFunc = true;
                    }
                    else
                    {
                        MessageBox.Show("Error: 'begin' in a function");
                        break;
                    }                  
                }
                else if (cmd == "end")
                {
                    if (isInFunc)
                    {
                        isInFunc = false;
                        funcs.Add(new Function(funcname, tmpCode));
                        tmpCode = "";
                        funcname = "";
                    }
                    else
                    {
                        MessageBox.Show("Error: 'end' must be in functions!");
                        break;
                    }
                }
                else
                {
                    if (isInFunc) tmpCode += cmd + '\n';
                    else { MessageBox.Show("Error: Code must be in functions:"); break; }

                    if (cmd.Split(':').Count() >= 1)
                    {
                        string type;
                        type = cmd.Split(' ')[0];
                        type = type.Substring(2);
                        type = type.Replace("}", "");
                        string varname;
                        varname = cmd.Split(' ')[1];
                        bool g = false;
                        foreach (Variable v in vars)
                        {
                            if (v.Name == varname)
                                g = true;
                        }
                        if (g)
                        {
                            MessageBox.Show("Error: variable '" + varname + "' defined twice!");
                            break;
                        }
                        else
                        {
                            if(type == "string")
                            {
                                if (StringImpl)
                                {
                                    vars.Add(new Variable(varname, null, typeof(string)));
                                }
                                else
                                {
                                    MessageBox.Show("Error: Unknown type 'string'");
                                }
                            }
                        }
                    }
                    else if ((cmd.Split(':')[0].StartsWith("def [")) && (cmd.Split(':')[0].EndsWith("]")))
                    {
                        string varname;
                        varname = cmd.Split(':')[0];
                        varname = varname.Substring(2);
                        varname = varname.Replace("]", "");

                        string value;
                        value = cmd.Split(':')[1];

                        Type vartype = null;

                        bool exists = false;

                        string defvalue = "";

                        foreach (Variable v in vars)
                        {
                            if (v.Name == varname)
                            {
                                vartype = v.Type;
                                exists = true;
                            }
                        }


                        if (!exists)
                        {
                            MessageBox.Show("Error: Undefined variable '" + varname + "'");
                            break;
                        }
                        if (vartype == typeof(string))
                        {
                            if (value.StartsWith("\"") && value.EndsWith("\""))
                            {
                                defvalue = value;
                                defvalue = defvalue.Substring(1);
                                defvalue = defvalue.Remove(defvalue.LastIndexOf('\"'));
                            }
                            else
                            {
                                MessageBox.Show("Error: Strings must be between quotes(\")");
                                break;
                            }
                        }

                        foreach (Variable v in vars)
                        {
                            if (v.Name == varname)
                            {
                                v.Value = defvalue;
                            }
                        }
                    }
                    else if (cmd.Split(':')[0][0] == '{' && cmd.Split(':')[0].EndsWith("}"))
                    {
                        string nm1 = cmd.Split(':')[0];
                        nm1 = nm1.Replace("{", "");
                        nm1 = nm1.Replace("}", "");

                        string fcname = "";

                        string args = "";

                        bool inarg = false;

                        foreach (char c in cmd.Split(':')[1])
                        {
                            if (!inarg)
                            {
                                if (c == '(')
                                {
                                    inarg = true;
                                }
                                else
                                {
                                    funcname += c;
                                }
                            }
                            else
                            {
                                if (c == ')')
                                {
                                    inarg = false;
                                }
                                else
                                {
                                    args += c;
                                }
                            }
                        }

                        switch (nm1)
                        {
                            case "app":
                                break;
                            case "console":

                                break;
                            case "this":
                                foreach (Function f in funcs)
                                {
                                    if (f.Name == fcname)
                                    {
                                        Run(f.InnerCode);
                                        break;
                                    }
                                }
                                break;
                        }
                    }
                    else
                    {

                    }
                }
                // Run the app
                bool m = false;
                foreach (Function f in funcs)
                {
                    if (f.Name == "main")
                    {
                        m = true;
                        Run(f.InnerCode);
                    }
                    else
                    {
                        m = false;
                    }
                }
                if (!m)
                {
                    MessageBox.Show("Error: No main function found!");
                    break;

                }
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void MainWindow_Load(object sender, EventArgs e)
        {
            /*MessageBox.Show(typeof(string).ToString());
            MessageBox.Show(typeof(string[]).ToString());
            var g = typeof(List<string>).ToString();
            var h = "g";
            MessageBox.Show(h);*/
        }
    }
}
